import GameView from "../../../../quick/core/ui/GameView";
import UILabel from "../../../../quick/core/ui/UILabel";
import { Update } from "../../../../quick/core/update/Update";
import { UpdateItem } from "../../../../quick/core/update/UpdateItem";
import { inject } from "../../../../quick/defines/Decorators";
import { Macro } from "../../../../quick/defines/Macros";
import SettingView from "../../../../scripts/common/component/SettingView";
import { ViewZOrder } from "../../../../scripts/common/config/Config";
import BundleMgrView from "../../../../scripts/common/view/BundleMgrView";

const { ccclass, property } = cc._decorator;

@ccclass
export default class HallView extends GameView {
    public static getPrefabUrl() {
        return "prefabs/HallView";
    }

    private onClick(ev: cc.Event.EventTouch) {
        this.enterBundle((ev.target as cc.Node).userData);
    }

    @inject("games",cc.Node)
    private gamePage: cc.Node = null;
    @inject("gameItem",cc.Node)
    private gameItem: cc.Node = null;
    @inject("pageview",cc.PageView)
    private pageView: cc.PageView = null;
    private readonly PAGE_COUNT = 6;

    private get data(){
        return App.stageData;
    }

    addEvents(): void {
        this.onD(Macro.ON_UPDATE_DOWNLOADING,this.onDownloadProgess);
        this.onD(Macro.ON_UPDATE_FAILED,this.toUpdateStatus);
        this.onD(Macro.ON_DELETE_BUNDLE_CACHE,this.onDeleteBundleCache)
        super.addEvents();
    }

    private createPage() {

        //计算出总页数
        let count = this.data.games.length;
        let pageCount = Math.ceil(count / this.PAGE_COUNT);
        for (let i = 0; i < pageCount; i++) {
            let page = cc.instantiate(this.gamePage);
            page.active = true;
            this.pageView.addPage(page);
        }

        for (let i = 0; i < count; i++) {
            let game = cc.instantiate(this.gameItem);
            let config = this.data.games[i];
            game.name = `game_${config.bundle}`;
            game.active = true;
            game.userData = config.bundle;
            cc.find("Background/label", game).getComponent(UILabel).language = config.language;
            this.onN(game,cc.Node.EventType.TOUCH_END, this.onClick);
            this.updateGameItemStatus(game);
            //计算出所有页
            let page = Math.floor(i / this.PAGE_COUNT);
            this.pageView.getPages()[page].addChild(game);
        }
    }

    onLoad() {
        super.onLoad();
        this.createPage();

        let bottom_op = cc.find("bottom_op", this.node);
        let setting = cc.find("setting", bottom_op);
        this.onN(setting,cc.Node.EventType.TOUCH_END, () => {
            App.uiManager.open({ type: SettingView, bundle: Macro.BUNDLE_RESOURCES, zIndex: ViewZOrder.UI, name: "设置界面" });
        });

        let mail = cc.find("mial", bottom_op);
        this.onN(mail,cc.Node.EventType.TOUCH_END,this.onMail);

        let bundleMgr = cc.find("shop",bottom_op);
        this.onN(bundleMgr,cc.Node.EventType.TOUCH_END,this.onBundleMgr)
    }

    private onBundleMgr(){
        App.uiManager.open({
            type : BundleMgrView,
            bundle : Macro.BUNDLE_RESOURCES,
            zIndex : ViewZOrder.UI,
            name : "Bundle管理"
        })
    }

    private onMail(){
        let lan = App.language.getLanguage();
        if (lan == cc.sys.LANGUAGE_CHINESE) {
            lan = cc.sys.LANGUAGE_ENGLISH
        } else if (lan == cc.sys.LANGUAGE_ENGLISH) {
            lan = cc.sys.LANGUAGE_CHINESE;
        }
        App.language.change(lan);
    }

    private getGameItem(bundle: string) {
        let pages = this.pageView.getPages();
        for (let i = 0; i < pages.length; i++) {
            let page = pages[i];
            let item = cc.find(`game_${bundle}`, page);
            if (item) {
                return item;
            }
        }
        return null;
    }

    private updateGameItemStatus(item: cc.Node) {
        let bundle = item.userData;
        let status = App.updateManager.getStatus(bundle);
        let updateNode = cc.find("Background/update", item);
        if (!updateNode) return;
        if (status == Update.Status.UP_TO_DATE) {
            updateNode.active = false;
            return;
        } else {
            updateNode.active = true;
        }
        let downloading = cc.find("downloading", updateNode);
        let down = cc.find("down", updateNode);
        let update = cc.find("update", updateNode);
        if (downloading && down && update) {
            if (status == Update.Status.NEED_DOWNLOAD) {
                downloading.active = false;
                down.active = true;
                update.active = false;
            } else {
                downloading.active = false;
                down.active = false;
                update.active = true;
            }
        }
    }

    private onDownloadProgess(item : UpdateItem ,info: Update.DownLoadInfo) {
        let node = this.getGameItem(info.bundle);
        if (node) {
            let updateNode = cc.find("Background/update", node);
            if (!updateNode) return;

            let downloading = cc.find("downloading", updateNode);
            let down = cc.find("down", updateNode);
            let update = cc.find("update", updateNode);
            if (downloading && down && update) {
                updateNode.active = true;
                let progressBar = cc.find(`downloading`, updateNode)?.getComponent(cc.ProgressBar);
                let progressLabel = cc.find(`downloading/progress`, updateNode)?.getComponent(cc.Label);
                down.active = false;
                update.active = false;

                if (progressBar && progressLabel) {
                    if (info.progress == -1) {
                        updateNode.active = false;
                    } else if (info.progress < 1) {
                        updateNode.active = true;
                        downloading.active = true;
                        progressBar.progress = info.progress;
                        progressLabel.string = `${(info.progress * 100).toFixed(2)}%`;
                    } else {
                        updateNode.active = false;
                    }
                }
            }
        }
    }

    private toUpdateStatus(item: UpdateItem) {
        let node = this.getGameItem(item.bundle);
        if ( !node ) return;
        let updateNode = cc.find("Background/update", node);
        if (!updateNode) return;
        updateNode.active = true;

        let downloading = cc.find("downloading", updateNode);
        let down = cc.find("down", updateNode);
        let update = cc.find("update", updateNode);
        if (downloading && down && update) {
            downloading.active = false;
            down.active = false;
            update.active = true;
        }
    }

    private onDeleteBundleCache(bundle:string){
        this.updateGameItemStatus(this.getGameItem(bundle));
    }

    show(args?: any[] | any) {
        super.show(args)
        let version = cc.find("version",this.node)?.getComponent(cc.Label);
        if ( version ){
            version.string = App.updateManager.getVersion(this.bundle);
        }
        this.audioHelper.playMusic("audio/background", this.bundle)
    }
}
